package com.study.spmongodb.book.wwj.char10;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * @author MI
 * @version 1.0
 * @date 2020/11/26 13:46
 */
//所有的自定义类加载器都是ClassLoader的直接之类或者间接之类
public class MyclassLoader extends ClassLoader {
    //定义默认的class存放路径
    private final static Path DEFAULT_CLASS_PATH =
            Paths.get("F", "classloader1");

    private final Path classDir;

    //使用默认的class路径

    public MyclassLoader() {
        super();
        this.classDir = DEFAULT_CLASS_PATH;
    }

    public MyclassLoader(String classDir, ClassLoader parent) {
        super(parent);
        this.classDir = Paths.get(classDir);
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        //读取class的二进制数据
        final byte[] classBytes = this.readClassBytes(name);
        if (null == classBytes || classBytes.length == 0) {
            throw new ClassNotFoundException("can not load the class " + name);
        }
        //调用class文件读入内存
        return this.defineClass(name, classBytes, 0, classBytes.length);
    }

    private byte[] readClassBytes(String name) throws ClassNotFoundException {
        //将包名分割符转为文件路径分隔符
        final String classPath = name.replace(".", "/");
        final Path classFullPath = classDir.resolve(Paths.get(classPath + ".class"));
        if (!classFullPath.toFile().exists()) {
            throw new ClassNotFoundException("THE class " + name + " not found.");
        }
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            Files.copy(classFullPath, baos);
            return baos.toByteArray();
        } catch (IOException e) {
            throw new ClassNotFoundException("THE class " + name + " occurerror .", e);
        }
    }

    @Override
    public String toString() {
        return "MyclassLoader{" +
                "classDir=" + classDir +
                '}';
    }
}
